package com.yc.thread.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockTest {

    static Lock lock = new ReentrantLock(true);

    public void m1() {
        for(int i=0;i<5;i++){
            new Thread(new ThreadDemo(i)).start();
        }
    }

    public void m2() {
        ReentrantLock mylock = new ReentrantLock();
        Condition c = mylock.newCondition();
        mylock.lock();
        try {
            c.await();//把自己阻塞
            c.signal();//把第一个阻塞的线程唤醒
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        mylock.unlock();
    }

    public void testReentrantLock() {
        ReentrantLock mylock = new ReentrantLock();

        mylock.lock();//抢锁 加锁
        System.out.println("------do something....");//线程安全操作
        mylock.unlock();//释放锁
    }

    public void testReentrantLockInterruptibly() {
        ReentrantLock mylock = new ReentrantLock();

        try {
            mylock.lockInterruptibly();//抢锁 加锁
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("------do something....");//线程安全操作
        mylock.unlock();//释放锁
    }

    public void testReentrantLock2() {
        ReentrantLock mylock = new ReentrantLock();
        Condition c = mylock.newCondition();

        mylock.lock();//抢锁 加锁
        System.out.println("------do something....");//线程安全操作
        try {
            c.await();//把自己阻塞
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        mylock.unlock();//释放锁
    }

    public void testReentrantLock2_1() {
        ReentrantLock mylock = new ReentrantLock();
        Condition c = mylock.newCondition();

        mylock.lock();//抢锁 加锁
        System.out.println("------do something....");//线程安全操作
        c.signal();//把阻塞的线程唤醒（配合await使用）
        mylock.unlock();//释放锁
    }

    public static void main(String[] args) throws InterruptedException {
        ReentrantLockTest t = new ReentrantLockTest();
//        t.m2();
        t.testReentrantLock2_1();
    }

    static class ThreadDemo implements Runnable {
        Integer id;

        public ThreadDemo(Integer id) {
            this.id = id;
        }

        @Override

      public void run() {
            try {
                TimeUnit.MILLISECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for(int i=0;i<2;i++){
                lock.lock();
                System.out.println("获得锁的线程："+id);
                lock.unlock();
            }
        }
    }
}
